{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a0c3b520",
   "metadata": {},
   "source": [
    "## 8.4 高级操作\n",
    "### 8.4.1 自动求导机制"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcfafae7",
   "metadata": {},
   "source": [
    "例：使用tf.GradientTape()计算函数y=x^2的x=3时的一阶导数\n",
    "\n",
    "注意，这里变量x要设置为浮点型，不能为整型。另外，变量x使用tf.Variable()声明，与普通张量一样，该变量拥有形状、类型和值这3种属性。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b79f9741",
   "metadata": {},
   "outputs": [],
   "source": [
    "#X是变量时\n",
    "import tensorflow as tf\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1dfcdc30",
   "metadata": {},
   "outputs": [],
   "source": [
    "#若将X定义为常量\n",
    "import tensorflow as tf\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2dff96ae",
   "metadata": {},
   "outputs": [],
   "source": [
    "#若对多个数求导，需要使用参数persistent=True\n",
    "import tensorflow as tf\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a30bad9",
   "metadata": {},
   "source": [
    "### 8.4.2 损失函数\n",
    "损失函数 (loss function），又称为目标函数，用于评估模型的预测值y ̃与真实值y的差异，一般来说为一个非负的实值函数，通常用L(y ̃,y)表示。损失函数越小，说明预测值y ̃与真实值y的差异越小，模型的预测越准确。损失函数的种类众多，损失函数的选择一般取决于模型或所解决的问题。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed5813ad",
   "metadata": {},
   "source": [
    "（1）交叉熵（CrossEntropy，CE）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "456ba75b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "y_true = [1, 0, 0]\n",
    "y_pred1 = [0.5, 0.4, 0.1]\n",
    "y_pred2 = [0.8, 0.1, 0.1]\n",
    "# y_true是one-hot编码,三分类问题采用多类别交叉熵损失函数计算损失\n",
    "print(tf.keras.losses.categorical_crossentropy(y_true, y_pred1))\n",
    "# y_pred2与真实值y_true较接近，其类别交叉熵越小\n",
    "print(tf.keras.losses.categorical_crossentropy(y_true, y_pred2))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba261ec3",
   "metadata": {},
   "source": [
    "（2）均方差"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f996f38f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "y_true = tf.constant([0.5, 0.8]) # 真实值\n",
    "y_pred = tf.constant([1.0, 1.0]) # 预测值# 计算真实值与预测值均方损失\n",
    "print(tf.keras.losses.MSE(y_true, y_pred))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52984103",
   "metadata": {},
   "source": [
    "（3）L1损失或平均绝对误差损失(Mean absolute error）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b74ff7ba",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 方式一：传递损失函数名方式编译模型\n",
    "#model.compile(loss='mean_squared_error', optimizer='sgd')\n",
    "# 方式二：传递Tensorflow符号函数编译模型\n",
    "from keras import losses\n",
    "#model.compile(loss=losses.mean_squared_error, optimizer='sgd')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2240ebc6",
   "metadata": {},
   "source": [
    "### 8.4.3 优化器\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ba372a2",
   "metadata": {},
   "source": [
    "### 8.4.4 激活函数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f8622b9",
   "metadata": {},
   "source": [
    "### 8.4.5 案例分析"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ed989a3",
   "metadata": {},
   "source": [
    "本节使用梯度更新函数的写法以某城市2013-2021年的房价数据进行预测，如下表所示。\n",
    "\n",
    "某城市2016-2021年房价表\n",
    "\n",
    "年份\t房价\n",
    "|2016--\t|12000\n",
    "2017\t14000\n",
    "2018\t15000\n",
    "2019\t16500\n",
    "2020\t17500\n",
    "2021\t17800\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d2128014",
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "#定义原数据\n",
    "x_raw=np.array([2016,2017,2018,2019,2020,2021],dtype=np.float32)\n",
    "y_raw=np.array([12000,14000,15000,16500,17500,17800],dtype=np.float32)\n",
    "#数据归一化\n",
    "\n",
    "#定义张量\n",
    "\n",
    "#定义参数a,b \n",
    "\n",
    "#定义迭代次数\n",
    "\n",
    "#定义优化器，用以更新参数\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "plt.scatter(x_raw,y_raw,c='r') #用散点图画出原始数据\n",
    "#画出预测线\n",
    "#plt.plot(x_raw,(a*((x_raw-x_raw.min())/(x_raw.max()-x_raw.min()))+b)*(y_raw.max()-y_raw.min())+y_raw.min())\n",
    "#plt.plot(x_raw,a*x_raw+b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "022056e2",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c8a2bc0f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
